﻿using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;

namespace NullTodoList
{
    class AnalogClock : UserControl
    {
        public const Int32 RADIUS_SIZE = 100;

        private TimeSpan time;

        public AnalogClock()
        {
            DoubleBuffered = true;
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            // Перо для рисования.
            var pen = new Pen(ForeColor);
            // Толщина пера.
            pen.Width = 2;
            // Конец пера закругленный.
            pen.EndCap = LineCap.Round;
            // Выравнивание пера посередине.
            pen.Alignment = PenAlignment.Center;
            // Размер компонента.
            // Устанавливаем режим сглаживания.
            e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
            // Смещаем начало координат в середину компонента.
            e.Graphics.TranslateTransform(Size.Width / 2, Size.Height / 2);
            // Рисуем метки.
            DrawLines(e.Graphics, pen);
            // Рисуем минутную стрелку.
            DrawHourHand(e.Graphics, pen);
            // Рисуем часовую стрелку.
            DrawMinuteHand(e.Graphics, pen);
            // Рисуем секундную стрелку.
            DrawSecondHand(e.Graphics, pen);
            base.OnPaint(e);
        }

        public static Single HourToAngle(TimeSpan time)
        {
            return 360f * time.Hours / 12 + 30f * time.Minutes / 60;
        }

        private void DrawLines(Graphics g, Pen pen)
        {
            pen.Width = RADIUS_SIZE / 50F;
            for (int i = 0; i < 60; i++)
            {
                int length = i % 5 == 0 ? RADIUS_SIZE / 5 : RADIUS_SIZE / 10;
                g.DrawLine(pen, 0, -RADIUS_SIZE, 0, -RADIUS_SIZE + length);
                g.RotateTransform(6);
            }
        }

        private void DrawHourHand(Graphics g, Pen pen)
        {
            var state = g.Save();
            g.RotateTransform(HourToAngle(time));
            pen.Width = RADIUS_SIZE / 16f;
            pen.StartCap = LineCap.RoundAnchor;
            g.DrawLine(pen, 0, 0, 0, -RADIUS_SIZE * 0.5F);
            g.Restore(state);
        }

        private void DrawMinuteHand(Graphics g, Pen pen)
        {
            var state = g.Save();
            g.RotateTransform(360f * time.Minutes / 60 + 6f * time.Seconds / 60);
            pen.Width = RADIUS_SIZE / 25f;
            g.DrawLine(pen, 0, 0, 0, -RADIUS_SIZE * 0.75F);
            g.Restore(state);
        }

        private void DrawSecondHand(Graphics g, Pen pen)
        {
            var state = g.Save();
            g.RotateTransform(360f * time.Seconds / 60 + 6f * time.Milliseconds / 1000);
            pen.Width = RADIUS_SIZE / 50f;
            g.DrawLine(pen, 0, 0, 0, -RADIUS_SIZE * 0.75F);
            g.Restore(state);
        }

        public TimeSpan Time
        {
            get
            {
                return time;
            }
            set
            {
                time = value;
                Invalidate();
            }
        }
    }
}
